package com.tyqx.biz.controller;

import com.tyqx.apiutil.common.CnyExchangeUsdRateUtil;
import com.tyqx.apiutil.common.DateUtil;
import com.tyqx.apiutil.common.GetUrlUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.tyqx.bean.model.*;
import com.tyqx.service.EthIncomeListService;
import com.tyqx.service.EthPoolInfoService;
import com.tyqx.service.RatesInfoService;
import com.tyqx.service.UserHashrateInfoService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.client.RestTemplate;
import org.web3j.utils.Convert;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@RequestMapping("/pool")
@Controller
public class InComeController {

    private static final Logger logger = LoggerFactory.getLogger(InComeController.class);


    @Resource
    private EthPoolInfoService ethPoolInfoService;

    @Resource
    private EthIncomeListService ethIncomeListService;

    @Resource
    private UserHashrateInfoService userHashrateInfoService;


    @Resource
    private RatesInfoService ratesInfoService;


    @RequestMapping("/eth/{userCode}")
    public String index1(@PathVariable("userCode")String userCode, @RequestParam(defaultValue = "1",value = "pageNum") Integer pageNumm, Model model){
        logger.debug("userCode:"+userCode);
        try {
            UserHashrateInfo userHashrateInfo = userHashrateInfoService.selectUserHashrateInfoByUserCode(userCode);
            if(null != userHashrateInfo) {
                Date currentDate = new Date();

                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");


                Date endDate = dateFormat.parse(dateFormat.format(currentDate));


                SimpleDateFormat df = new SimpleDateFormat("HH:mm");// 设置日期格式
                Date now = null;
                Date beginTime = null;
                Date endTime = null;
                try {
                    now = df.parse(df.format(new Date()));
                    beginTime = df.parse("00:00");
                    endTime = df.parse("08:00");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                Boolean flag = DateUtil.belongCalendar(now, beginTime, endTime);

                if(flag){
                    Calendar rightNow1 = Calendar.getInstance();
                    rightNow1.setTime(endDate);
                    rightNow1.add(Calendar.DAY_OF_YEAR, -1);//日期减去一天

                    endDate = dateFormat.parse(dateFormat.format(rightNow1.getTime()));
                }

                Calendar rightNow = Calendar.getInstance();
                rightNow.setTime(endDate);
                rightNow.add(Calendar.DAY_OF_YEAR, -1);//日期减去一天

                Date startDate = dateFormat.parse(dateFormat.format(rightNow.getTime()));

                //今天
                List<EthPoolInfo> ethPoolInfoCurrentDayList = ethPoolInfoService.selectEthPoolInfoByCurrentDay(endDate);

                //今天总奖励
                Double rewardCurrentDayCount = new Double(0);

                //今天总算力
                Double hashRateCurrentDayCount = new Double(0);


                for (int i = 0; i < ethPoolInfoCurrentDayList.size(); i++) {
                    EthPoolInfo ethPoolInfo = ethPoolInfoCurrentDayList.get(i);
                    hashRateCurrentDayCount = hashRateCurrentDayCount + ethPoolInfo.getHashRate();
                    rewardCurrentDayCount = rewardCurrentDayCount + ethPoolInfo.getReward();
                }


               RestTemplate restTemplate = new RestTemplate();
                Map<String, String> params = new HashMap<>();
                String ApiKeyToken = "ASWSS28IBQI6WRJ6BQNQC1RVM5QDVM2G7E";
                params.put("ApiKeyToken", ApiKeyToken);
                ResponseEntity<String> forEntity = restTemplate.getForEntity("https://api-cn.etherscan.com/api?module=stats&action=ethprice&apikey={ApiKeyToken}", String.class, params);
                String body = forEntity.getBody();
                JSONObject ethpriceObject = JSON.parseObject(body);

                JSONObject result5 = ethpriceObject.getJSONObject("result");


                String url = "https://etherchain.org/api/basic_stats";
                String param = "";
                String basicStats = GetUrlUtil.GetUrl(url, param);
                JSONObject basicStatsJson = JSON.parseObject(basicStats);
                JSONObject currentStats = basicStatsJson.getJSONObject("currentStats");

                //当前eth全网平均算力
                BigDecimal currentHashrate = currentStats.getBigDecimal("hashrate");

                //当前eth美元价格
                BigDecimal priceUsd = new BigDecimal(result5.getString("ethusd"));

//                String currentDateDayStr = dateFormat.format(endDate);
//
//                if(ratesInfoService.selectRatesInfoByDate(currentDateDayStr) == null){
//                    Calendar rightNow1 = Calendar.getInstance();
//                    rightNow1.setTime(endDate);
//                    rightNow1.add(Calendar.DAY_OF_YEAR, -1);//日期减去一天
//
//                    endDate = dateFormat.parse(dateFormat.format(rightNow1.getTime()));
//                    currentDateDayStr = dateFormat.format(endDate);
//                }
                //获取美元兑换人民币汇率
                Double cnyRate = ratesInfoService.selectRatesInfoByDate().getRates();



                String priceCnyStr = "";
                //cnyRate = null;
                //cnyRate = 0.0;
                if(cnyRate >0){
                    //当前eth人民币价格
                    BigDecimal priceCny = priceUsd.multiply(new BigDecimal(cnyRate)).setScale(4,BigDecimal.ROUND_HALF_UP);
                    priceCnyStr = "ETH实时价格(¥)："+priceCny;
                }else{
                    priceCnyStr = "ETH实时价格(＄)："+priceUsd;
                }



                //当前区块平均难度
                BigDecimal currentDifficulty = currentStats.getBigDecimal("difficulty");

                BigDecimal hashrateAvg = new BigDecimal(userHashrateInfo.getHashrateAvg()).setScale(8, BigDecimal.ROUND_HALF_UP);

                //平均算力hash/s 转gh/s
                currentHashrate = currentHashrate.movePointLeft(9);

                //算力比例
                BigDecimal computingPowerRatio = hashrateAvg.divide(currentHashrate, 20, BigDecimal.ROUND_HALF_UP);

                BigDecimal todayPaid = new BigDecimal(0);
                EthIncomeList ethIncomeList = ethIncomeListService.selectEthIncomeListByProductDate(startDate, userHashrateInfo.getUserCode());
                if (null == ethIncomeList) {
                    Calendar rightNow1 = Calendar.getInstance();
                    rightNow1.setTime(startDate);
                    rightNow1.add(Calendar.DAY_OF_YEAR, -1);

                    Date startDate1 = dateFormat.parse(dateFormat.format(rightNow1.getTime()));
                    EthIncomeList ethIncomeList1 = ethIncomeListService.selectEthIncomeListByProductDate(startDate1, userHashrateInfo.getUserCode());
                    todayPaid = BigDecimal.valueOf(ethIncomeList1.getPaid());
                    Double miningHours2 = ethIncomeList1.getMiningHours();
                    //当前工作小时数除以24小时
                    BigDecimal miningHoursRateBigDecimal2 = new BigDecimal(miningHours2).divide(BigDecimal.valueOf(24),4,BigDecimal.ROUND_HALF_UP);

                    todayPaid = new BigDecimal(ethIncomeList1.getPaid()).multiply(miningHoursRateBigDecimal2).setScale(8,BigDecimal.ROUND_HALF_UP);

                } else {
                    todayPaid = BigDecimal.valueOf(ethIncomeList.getPaid());
                    Double miningHours1 = ethIncomeList.getMiningHours();
                    //当前工作小时数除以24小时
                    BigDecimal miningHoursRateBigDecimal1 = new BigDecimal(miningHours1).divide(BigDecimal.valueOf(24),4,BigDecimal.ROUND_HALF_UP);

                    todayPaid = new BigDecimal(ethIncomeList.getPaid()).multiply(miningHoursRateBigDecimal1).setScale(8,BigDecimal.ROUND_HALF_UP);

                }

                //今日已挖
                BigDecimal valueToday = computingPowerRatio.multiply(BigDecimal.valueOf(rewardCurrentDayCount));
                valueToday = valueToday.multiply(new BigDecimal(0.97));
                valueToday = valueToday.setScale(8, BigDecimal.ROUND_HALF_UP);

                Integer pageSize = 10;

                //收益记录

                List<EthIncomeList> ethIncomeLists = ethIncomeListService.selectEthIncomeListsByUserCode(userCode);
                List<EthIncomeList> ethIncomeListsPage = ethIncomeListService.selectEthIncomeListsByUserCodeAndPage(userCode,pageNumm,pageSize);

                List<EthIncomeListVO> ethIncomeListVOList = new ArrayList<>();

                List<EthIncomeListVO> ethIncomeListVOListPage = new ArrayList<>();

                for (EthIncomeList ethIncome:ethIncomeLists) {
                    Date productDate = ethIncome.getProductDate();
                    Double miningHours = ethIncome.getMiningHours();
                    //当前工作小时数除以24小时
                    BigDecimal miningHoursRateBigDecimal = new BigDecimal(miningHours).divide(BigDecimal.valueOf(24),4,BigDecimal.ROUND_HALF_UP);

                    BigDecimal incomeNew = new BigDecimal(ethIncome.getPaid()).multiply(miningHoursRateBigDecimal).setScale(8,BigDecimal.ROUND_HALF_UP);

                    EthIncomeListVO ethIncomeListVO = new EthIncomeListVO();
                    ethIncomeListVO.setEthNum(incomeNew.doubleValue());
                    ethIncomeListVO.setProductDate(productDate);
                    ethIncomeListVO.setMiningHours(miningHours);

                    ethIncomeListVOList.add(ethIncomeListVO);

                }

                for (EthIncomeList ethIncome:ethIncomeListsPage) {
                    Date productDate = ethIncome.getProductDate();
                    Double miningHours = ethIncome.getMiningHours();
                    //当前工作小时数除以24小时
                    BigDecimal miningHoursRateBigDecimal = new BigDecimal(miningHours).divide(BigDecimal.valueOf(24),4,BigDecimal.ROUND_HALF_UP);

                    BigDecimal incomeNew = new BigDecimal(ethIncome.getPaid()).multiply(miningHoursRateBigDecimal).setScale(8,BigDecimal.ROUND_HALF_UP);

                    EthIncomeListVO ethIncomeListVO = new EthIncomeListVO();
                    ethIncomeListVO.setEthNum(incomeNew.doubleValue());
                    ethIncomeListVO.setProductDate(productDate);
                    ethIncomeListVO.setMiningHours(miningHours);

                    ethIncomeListVOListPage.add(ethIncomeListVO);

                }

                Integer totalCount = ethIncomeListService.selectCountByUserCode(userCode);


                //帐户余额
                BigDecimal balance = new BigDecimal(0);
                for (EthIncomeListVO ethIncome:ethIncomeListVOList) {
                    balance = balance.add(new BigDecimal(ethIncome.getEthNum())).setScale(8,BigDecimal.ROUND_HALF_UP);
                }

                Integer totalPages = totalCount / pageSize;
                if (totalCount % pageSize != 0){
                    totalPages ++;
                }

                model.addAttribute("priceCnyStr", priceCnyStr);
                model.addAttribute("todayPaid", todayPaid);
                model.addAttribute("valueToday", valueToday);
                model.addAttribute("balance", balance);
                model.addAttribute("ethIncomeLists", ethIncomeListVOListPage);
                model.addAttribute("totalCount", totalCount);
                model.addAttribute("pageNum", pageNumm);
                model.addAttribute("pageSize",ethIncomeListsPage.size());
                model.addAttribute("totalPages",totalPages);
                model.addAttribute("userCode", userCode);
            }else{
                return "404/index";
            }

        } catch (Exception e) {
            e.printStackTrace();
        }



        return "inComeIndex";
    }

    @RequestMapping(value = "/eth/inComeDay",produces = {"application/json;charset=UTF-8"})
    @ResponseBody
    public String inComeDay(@RequestParam("days")String days){
        if(days == "" || days == null){
            return "请填写Days,格式为yyyy-MM-dd,yyyy-MM-dd";
        }

        String[] dayList = days.split(",");

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");

        List<Date> dayDateList = new ArrayList<>();

        String dayFormatErrorStr = "";
        for(String day : dayList){
            try{
                format.setLenient(false);
                Date dayDate = format.parse(day);
                dayDateList.add(dayDate);
            }catch (Exception e){
                e.printStackTrace();
                logger.debug(day + ":日期格式不正确");
                dayFormatErrorStr = dayFormatErrorStr +  day + ":日期格式不正确\n\n";
            }
        }
        if(!"".equals(dayFormatErrorStr)){
            return dayFormatErrorStr;
        }

        RestTemplate restTemplate = new RestTemplate();
        Map<String,String> params = new HashMap<>();
        String address = "0x62dD3a1d95DB1E4BeD53001291BF04c3f689B515";
        params.put("address",address);


        for (Date dayDate : dayDateList){
            try {
                SimpleDateFormat dateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");


                dayDate = dateFormat.parse(dateFormat.format(dayDate));

                Calendar rightNow = Calendar.getInstance();
                rightNow.setTime(dayDate);
                rightNow.add(Calendar.DAY_OF_YEAR,+ 1);//日期减1天



                Date startDate=dateFormat.parse(dateFormat.format(dayDate));

                Date endDate = dateFormat.parse(dateFormat.format(rightNow.getTime()));


                //今天
                List<EthPoolInfo> ethPoolInfoList = ethPoolInfoService.selectEthPoolInfoByStartDateToEndDate(startDate,endDate);


                Long startBlock = ethPoolInfoList.get(0).getBlock();
                Long endBlock = ethPoolInfoList.get(ethPoolInfoList.size()-1).getBlock();

                //过去24小时总区块
                Long blockCount =  endBlock - startBlock + 1;

                //过去24小时总奖励
                Double rewardCount = new Double(0);


                //过去24小时总算力
                Double hashRateCount = new Double(0);


                for (int i=0;i<ethPoolInfoList.size();i++){
                    EthPoolInfo ethPoolInfo = ethPoolInfoList.get(i);
                    hashRateCount = hashRateCount + ethPoolInfo.getHashRate();
                    rewardCount = rewardCount + ethPoolInfo.getReward();
                }



                Double currentHashrateDouble = ethPoolInfoList.get(ethPoolInfoList.size()-1).getHashRate();

                //当前eth全网平均算力
                BigDecimal currentHashrate1 = new BigDecimal(currentHashrateDouble);


                //当前区块平均难度
                BigDecimal currentDifficulty = new BigDecimal(ethPoolInfoList.get(ethPoolInfoList.size()-1).getDifficulty());



                BigDecimal daySeconds = new BigDecimal(24*60*60);

                List<UserHashrateVo> userHashrateVoList = new ArrayList<>();
                List<UserHashrateInfo> userHashrateInfoList = userHashrateInfoService.selectUserHashrateInfos();

                for (int i=0;i<userHashrateInfoList.size();i++){
                    UserHashrateInfo userHashrateInfo = userHashrateInfoList.get(i);
                    UserHashrateVo userHashrateVo1 = new UserHashrateVo();
                    userHashrateVo1.setUserCode(userHashrateInfo.getUserCode());
                    userHashrateVo1.setHashrate(new BigDecimal(userHashrateInfo.getHashrateAvg()).setScale(8,BigDecimal.ROUND_HALF_UP));
                    userHashrateVoList.add(userHashrateVo1);
                }

                //平均算力hash/s 转gh/s
//                currentHashrate = currentHashrate.movePointLeft(9);

                for (int j=0;j<userHashrateVoList.size();j++){
                    UserHashrateVo userHashrateVo2 = userHashrateVoList.get(j);
                    String userCode = userHashrateVo2.getUserCode();
                    BigDecimal hashrate = userHashrateVo2.getHashrate();



                    //算力比例
                    BigDecimal computingPowerRatio = hashrate.divide(currentHashrate1,10, BigDecimal.ROUND_HALF_UP);

                    //昨日收益
                    BigDecimal todayPaid = computingPowerRatio.multiply(BigDecimal.valueOf(rewardCount));

                    todayPaid = todayPaid.multiply(new BigDecimal(0.97));

                    todayPaid = todayPaid.setScale(8,BigDecimal.ROUND_HALF_UP);


                    EthIncomeList ethIncomeList = ethIncomeListService.selectEthIncomeListByProductDate(startDate,userCode);
                    if(null == ethIncomeList){
                        EthIncomeList ethIncomeList1 = new EthIncomeList();
                        ethIncomeList1.setPaid(todayPaid.doubleValue());
                        ethIncomeList1.setProductDate(startDate);
                        ethIncomeList1.setBlockCount(blockCount);
                        ethIncomeList1.setCreateDate(dateFormat1.parse(dateFormat1.format(new Date())));
                        ethIncomeList1.setCurrentDifficulty(currentDifficulty.longValue());
                        ethIncomeList1.setComputingPowerRatio(computingPowerRatio.doubleValue());
                        ethIncomeList1.setHashRateCount(hashRateCount);
                        ethIncomeList1.setWeHashrateAvg(hashrate.doubleValue());
                        ethIncomeList1.setWholeNetworkCurrentHashrateAvg(currentHashrate1.doubleValue());
                        ethIncomeList1.setRewardCount(rewardCount);
                        ethIncomeList1.setUserCode(userCode);
                        ethIncomeList1.setMiningHours(24.00);

                            Integer flag = ethIncomeListService.insert(ethIncomeList1);
                            if (flag > 0) {
                                logger.debug(dayDate + "新增收益记录成功");
                            } else {
                                logger.error(dayDate + "新增收益记录失败");
                            }
                    }else{
                        ethIncomeList.setPaid(todayPaid.doubleValue());
                        ethIncomeList.setProductDate(startDate);
                        ethIncomeList.setBlockCount(blockCount);
                        ethIncomeList.setCreateDate(dateFormat1.parse(dateFormat1.format(new Date())));
                        ethIncomeList.setComputingPowerRatio(computingPowerRatio.doubleValue());
                        ethIncomeList.setHashRateCount(hashRateCount);
                        ethIncomeList.setWeHashrateAvg(hashrate.doubleValue());
                        ethIncomeList.setWholeNetworkCurrentHashrateAvg(currentHashrate1.doubleValue());
                        ethIncomeList.setRewardCount(rewardCount);
                        ethIncomeList.setUserCode(userCode);
                        ethIncomeList.setMiningHours(24.00);
                        Integer flag = ethIncomeListService.update(ethIncomeList);
                        if (flag > 0) {
                            logger.debug(dayDate + "修改收益记录成功");
                        } else {
                            logger.error(dayDate + "修改收益记录失败");
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
                return "执行失败,发生错误";
            }

        }


        return "执行成功";
    }


}
